﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace _1231
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Person person1 = new Person();
            person1.Date = "2000";
            person1.Name = "直接赋值";
            person1.Cal_Age();   //转换年龄后打印


            Person person2 = new Person("三参数 构造器重载", "2021", '女');
            person2.Cal_Age();   //转换年龄后打印

            Person person3 = new Person("两参数 构造器重载", "2002");
            person3.Cal_Age();   //转换年龄后打印

            Person person4 = new Person();  //无参数 构造器重载
            person4.Cal_Age();   //转换年龄后打印

            Console.WriteLine("-----子类-----");

            Student student1 = new Student();
            student1.Student_ID = "20220325111";
            student1.Student_School = "河南科技学院";
            student1.Name = "子类继承父类直接赋值";
            student1.Gender = '女';
            student1.Date = "2004";
            student1.Print_info();  //打印信息

            Student student2 = new Student("20220325111","河南科技学院", "使用子类构造器 和 父类构造器直接赋值", "2005",'男');
            student2.Print_info();  //打印信息
        }

    }

    public class Person
    {
        public string Name;
        public string Date;

        /// <summary>
        /// 定义了一个名为 Gender 的属性,
        /// 通过 get 和 set 访问器来控制对私有字段 gender 的读取和写入操作。
        /// </summary>
        private char gender = '男';
        public char Gender
        {
            get { return gender; }
            set 
            {
                if (gender == '男' || gender == '女')
                {
                    gender = value;
                }
                else
                {
                    Console.WriteLine("性别只能为男或女");
                }
            }
        }

        /// <summary>
        /// 在 C# 中，当我们写好一个类之后，如果没有进行额外的操作，
        /// 系统会自动提供一个默认的构造器。
        /// 这个默认构造器会将类中没有赋值的参数初始化为默认值
        /// （所以每个类中都有一个没有参数的构造器）
        /// 
        /// 当然，我们还可以在创建实例时要求给变量初始值（带参数的构造器）
        /// 这就是构 *造函数重载 。
        /// </summary>
        public Person(string name, string date, char gender)    //构造函数重载为,三个参数，
        {
            this.Name = name;
            this.Date = date;
            this.Gender = gender;
        }
        public Person(string name, string date)    //构造函数重载为,两个参数，
        {
            this.Name = name;
            this.Date = date;
            this.Gender = '男';
        }
        public Person()    //构造函数重载为,无参数，
        {
            this.Name = "无参数 构造器重载";
            this.Date = "2003";
            this.Gender = '男';
        }

        /// <summary>
        /// 定义了一个名为 Gender 的属性,
        /// 通过 get 和 set 访问器来控制对私有字段 gender 的读取和写入操作。
        /// </summary>
        public int Cal_Age()
        { 
            int age_t = Convert.ToInt32(Date.Substring(0, 4));   //从这个字符串中取出前4位,然后转换为int32的整数类型，赋值给age
            Console.WriteLine("(父类转换)姓名：{0} 性别：{1} 年龄：{2}", Name, gender, age_t);
            return age_t;
        }
    }


    /// <summary>
    /// 派生（继承）：用法是  子类方法名:父类方法名子类 
    /// 会继承 父类的所有方法。
    /// 子类可以在类中创建与父类 相同名称 的方法，
    /// 并在前缀加入new 修饰符。来覆盖（或隐藏）父类的方法。
    /// 然后在子类中调用方法就是子类中创建的方法。父类调用则还是父类的方法。
    /// </summary>
    public class Student:Person
    {
        public string Student_ID;       //20220325111
        public string Student_School;   //河南科技学院

        public Student()    //创建构造器，初始化这两个变量
        {
            //Console.WriteLine("Person的子类：无参数的Student的构造函数");
            Student_ID = "20220325111";
            Student_School = "河南科技学院";
        }

        public Student(string ID, string School)    //创建构造器，自定义初始化这两个变量
        {
            //Console.WriteLine("Person的子类：有两个参数的Student的构造函数");
            Student_ID = ID;
            Student_School = School;
        }

        public Student(string ID, string School, string name, string date, char gender) : base(name, date, gender)    //创建构造器，初始化子类和父类变量
        {
            //Console.WriteLine("Person的子类：有四个参数（子类和父类）的Student的构造函数");
            // 也可以通过属性赋值父类的公开成员变量
            Student_ID = ID;
            Student_School = School;
            Name = name;
            Date = date;
            Gender = gender;
        }


        public void Print_info()
        {
            Console.WriteLine("姓名：{0} 性别：{1} 年龄：{2} 学校：{3} 学号：{4}",Name, Gender, Cal_Age(), Student_School, Student_ID );
        }
    }
}
